use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use anyhow::Result;
use log::{debug, info};
use serde_json::json;

use crate::project::Project;

/// VS Code C/C++ 插件配置结构
#[derive(Debug)]
pub struct CppPropertiesConfig {
    pub name: String,
    pub include_path: Vec<String>,
    pub defines: Vec<String>,
    pub compiler_path: Option<String>,
    pub c_standard: String,
    pub cpp_standard: String,
    pub intellisense_mode: String,
    pub qt_dir: Option<String>,  // 添加Qt目录字段
}

impl Default for CppPropertiesConfig {
    fn default() -> Self {
        Self {
            name: "Win32".to_string(),
            include_path: Vec::new(),
            defines: Vec::new(),
            compiler_path: None,
            c_standard: "c17".to_string(),
            cpp_standard: "c++17".to_string(),
            intellisense_mode: "windows-msvc-x64".to_string(),
            qt_dir: None,
        }
    }
}

impl CppPropertiesConfig {    /// 从项目列表生成配置
    pub fn from_projects(projects: &[&Project], qt_dir: Option<&String>) -> Self {
        let mut config = CppPropertiesConfig::default();
        
        // 收集所有包含目录
        let mut include_paths = std::collections::HashSet::new();
        
        // 使用工作区文件夹的通配符模式来包含所有项目文件
        include_paths.insert("${workspaceFolder}/**".to_string());
        
        // 添加vcpkg包含路径
        include_paths.insert("${vcpkgRoot}/x64-windows/include".to_string());
        
        // 添加Qt路径（如果提供）
        if let Some(qt_dir) = qt_dir {
            config.add_qt_paths(qt_dir, &mut include_paths);
        }
        
        // 收集所有预处理器定义
        let mut defines = std::collections::HashSet::new();
        for project in projects {
            for (_, defs) in &project.preprocessor_defs {
                for def in defs {
                    if !def.is_empty() {
                        defines.insert(def.clone());
                    }
                }
            }
        }
        
        // 添加Windows常用定义
        defines.insert("WIN32".to_string());
        defines.insert("_WINDOWS".to_string());
        defines.insert("UNICODE".to_string());
        defines.insert("_UNICODE".to_string());
        
        config.include_path = include_paths.into_iter().collect();
        config.include_path.sort();
        
        config.defines = defines.into_iter().collect();
        config.defines.sort();
          // 尝试查找编译器路径
        config.compiler_path = config.find_msvc_compiler();
        
        // 保存Qt目录
        config.qt_dir = qt_dir.cloned();
        
        config
    }
    
    /// 添加Qt路径
    fn add_qt_paths(&self, qt_dir: &str, include_paths: &mut std::collections::HashSet<String>) {
        let qt_base = qt_dir.replace('\\', "/");
        
        // Qt主要包含目录
        include_paths.insert(format!("{}/include", qt_base));
        include_paths.insert(format!("{}/include/QtCore", qt_base));
        include_paths.insert(format!("{}/include/QtGui", qt_base));
        include_paths.insert(format!("{}/include/QtWidgets", qt_base));
        include_paths.insert(format!("{}/include/QtNetwork", qt_base));
        include_paths.insert(format!("{}/include/QtOpenGL", qt_base));
        include_paths.insert(format!("{}/include/QtSql", qt_base));
        include_paths.insert(format!("{}/include/QtXml", qt_base));
        include_paths.insert(format!("{}/include/QtConcurrent", qt_base));
        include_paths.insert(format!("{}/include/QtTest", qt_base));
        include_paths.insert(format!("{}/include/QtPrintSupport", qt_base));
        
        // mkspecs目录
        include_paths.insert(format!("{}/.mkspecs/win32-msvc", qt_base));
    }
    
    /// 查找MSVC编译器路径
    fn find_msvc_compiler(&self) -> Option<String> {
        let possible_paths = [
            "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/*/bin/Hostx64/x64/cl.exe",
            "C:/Program Files/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/*/bin/Hostx64/x64/cl.exe",
            "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/*/bin/Hostx64/x64/cl.exe",
            "C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/*/bin/Hostx64/x64/cl.exe",
        ];
        
        for pattern in &possible_paths {
            // 简单实现：返回第一个可能的路径模式
            // 在实际使用中，VS Code会解析通配符
            return Some(pattern.to_string());
        }
        
        None
    }
      /// 生成VS Code配置文件
    pub fn generate_json_file(&self, output_dir: &Path) -> Result<()> {
        info!("生成 VS Code 配置文件");
        
        // 创建.vscode目录
        let vscode_dir = output_dir.join(".vscode");
        fs::create_dir_all(&vscode_dir)?;
        
        // 生成 c_cpp_properties.json
        self.generate_cpp_properties(&vscode_dir)?;
        
        // 生成 launch.json
        self.generate_launch_config(&vscode_dir)?;
        
        info!("VS Code 配置文件生成完成");
        Ok(())
    }
    
    /// 生成c_cpp_properties.json文件
    fn generate_cpp_properties(&self, vscode_dir: &Path) -> Result<()> {
        let json_content = json!({
            "configurations": [
                {
                    "name": self.name,
                    "includePath": self.include_path,
                    "defines": self.defines,
                    "compilerPath": self.compiler_path,
                    "cStandard": self.c_standard,
                    "cppStandard": self.cpp_standard,
                    "intelliSenseMode": self.intellisense_mode
                }
            ],
            "version": 4
        });
        
        let json_path = vscode_dir.join("c_cpp_properties.json");
        let mut file = File::create(&json_path)?;
        let formatted_json = serde_json::to_string_pretty(&json_content)?;
        file.write_all(formatted_json.as_bytes())?;
        
        info!("成功生成 c_cpp_properties.json: {}", json_path.display());
        debug!("配置内容:\n{}", formatted_json);
        Ok(())
    }    /// 生成launch.json文件
    fn generate_launch_config(&self, vscode_dir: &Path) -> Result<()> {
        // 构建环境变量，包含Qt路径（如果存在）
        let mut environment_vars = vec![
            json!({
                "name": "PATH",
                "value": self.build_path_value()
            })
        ];
        
        // 如果有Qt目录，添加Qt相关的环境变量
        if let Some(qt_dir) = &self.qt_dir {
            let qt_base = qt_dir.replace('\\', "\\\\"); // 转义反斜杠用于JSON
            environment_vars.push(json!({
                "name": "QT_DIR", 
                "value": qt_base
            }));
        }
        
        let launch_content = json!({
            "version": "0.2.0",
            "configurations": [
                {
                    "name": "(msvc) Launch",
                    "type": "cppvsdbg",
                    "request": "launch",
                    // Resolved by CMake Tools:
                    "program": "${command:cmake.launchTargetPath}",
                    "args": [],
                    "stopAtEntry": false,
                    "cwd": "${workspaceFolder}",
                    "environment": environment_vars,
                    "externalConsole": true
                }
            ]
        });
        
        let launch_path = vscode_dir.join("launch.json");
        let mut file = File::create(&launch_path)?;
        let formatted_json = serde_json::to_string_pretty(&launch_content)?;
        file.write_all(formatted_json.as_bytes())?;
        
        info!("成功生成 launch.json: {}", launch_path.display());
        debug!("配置内容:\n{}", formatted_json);
        Ok(())
    }
    
    /// 构建PATH环境变量值
    fn build_path_value(&self) -> String {
        let mut path_value = "${env:PATH};${command:cmake.getLaunchTargetDirectory}".to_string();
        
        // 如果有Qt目录，添加Qt bin路径
        if let Some(qt_dir) = &self.qt_dir {
            let qt_bin_path = format!("{}/bin", qt_dir.replace('\\', "/"));
            path_value.push_str(&format!(";{}", qt_bin_path));
        } else {
            // 尝试从include路径推断Qt路径
            for include_path in &self.include_path {
                if include_path.contains("Qt") && include_path.contains("include") {
                    // 从include路径推断bin路径
                    let qt_base = include_path.replace("/include", "").replace("\\include", "");
                    path_value.push_str(&format!(";{}/bin", qt_base));
                    break;
                }
            }
        }
        
        path_value
    }
}



#[cfg(test)]
mod tests {    use super::*;
    
    #[test]
    fn test_cpp_properties_config_default() {
        let config = CppPropertiesConfig::default();
        assert_eq!(config.name, "Win32");
        assert_eq!(config.c_standard, "c17");
        assert_eq!(config.cpp_standard, "c++17");
        assert_eq!(config.intellisense_mode, "windows-msvc-x64");
    }
      #[test]
    fn test_from_projects_empty() {
        let projects = vec![];
        let config = CppPropertiesConfig::from_projects(&projects, None);
        
        // 应该包含工作区通配符路径
        assert!(config.include_path.contains(&"${workspaceFolder}/**".to_string()));
        
        // 应该包含vcpkg路径
        assert!(config.include_path.contains(&"${vcpkgRoot}/x64-windows/include".to_string()));
        
        // 应该包含基本的Windows定义
        assert!(config.defines.contains(&"WIN32".to_string()));
        assert!(config.defines.contains(&"_WINDOWS".to_string()));
    }
}
